package com.wydpp.gb28181.commander;

import com.github.benmanes.caffeine.cache.Cache;
import com.wydpp.gb28181.bean.SipDevice;
import com.wydpp.gb28181.bean.SipPlatform;
import com.wydpp.gb28181.event.SipSubscribe;
import com.wydpp.model.response.BackTime;
import com.wydpp.model.response.BackTimeList;
import com.wydpp.utils.DateUtil;
import com.wydpp.utils.HttpUtil;
import com.wydpp.model.response.JTToGB;
import com.wydpp.model.response.OrgnizationInfo;
import com.wydpp.xml.xml;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import javax.sip.InvalidArgumentException;
import javax.sip.SipException;
import javax.sip.SipProvider;
import javax.sip.header.CallIdHeader;
import javax.sip.header.WWWAuthenticateHeader;
import javax.sip.message.Request;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.UUID;

/**
 * @description:设备能力接口
 * @author: wydpp
 * @date: 2021年12月2日
 */
@Component
public class SIPCommander implements ISIPCommander {
    // 定义原始日期时间格式
    private final static SimpleDateFormat originalFormat = new SimpleDateFormat("yyMMddHHmmss");

    // 定义目标日期时间格式
    private final static SimpleDateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    /**
     * 将字符串格式化成日期时间格式
     * @param input 输入字符串，例如 "250206000001"
     * @return 格式化后的日期时间字符串，例如 "2025-02-06 00:00:01"
     */
    public static String formatDateTime(String input) {
        // 提取日期和时间部分
        String datePart = input.substring(0, 6);
        String timePart = input.substring(6, 12);

        // 组合成原始日期时间字符串
        String originalDateTime = datePart + timePart;
        try {
            // 解析原始日期时间字符串
            Date date = originalFormat.parse(originalDateTime);

            // 格式化为目标日期时间字符串
            return targetFormat.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }


    private Logger logger = LoggerFactory.getLogger(SIPCommander.class);
    @Autowired
    private HttpUtil httpUtil;
    @Autowired
    Cache<String, Object> caffeineCache;

    @Autowired
    private SIPRequestHeaderPlatformProvider headerProviderPlatformProvider;

    @Autowired
    private SipSubscribe sipSubscribe;

    @Lazy
    @Autowired
    private SipProvider udpSipProvider;

    @Override
    public boolean register(SipPlatform sipPlatform, SipDevice sipDevice, SipSubscribe.Event okEvent) {
        return register(sipPlatform, sipDevice, null, null, okEvent);
    }

    @Override
    public boolean register(SipPlatform sipPlatform, SipDevice sipDevice, String callId, WWWAuthenticateHeader www, SipSubscribe.Event okEvent) {
        String tm = Long.toString(System.currentTimeMillis());
        Request request = null;
        CallIdHeader callIdHeader = udpSipProvider.getNewCallId();
        if (www == null) {
            try {
                request = headerProviderPlatformProvider.createRegisterRequest(sipPlatform, sipDevice, 1L, "FromRegister" + tm, null, callIdHeader);
            } catch (Exception e) {
                logger.error("createRegisterRequest error!", e);
            }
        } else {
            try {
                callIdHeader.setCallId(callId);
                request = headerProviderPlatformProvider.createRegisterRequest(sipPlatform, sipDevice, "FromRegister" + tm, null, www, callIdHeader);
            } catch (Exception e) {
                logger.error("createRegisterRequest error!", e);
            }
        }
        if (request != null) {
            if (okEvent != null) {
                sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), okEvent);
            }
            try {
                logger.info("要发送的注册消息:\n{}", request);
                udpSipProvider.sendRequest(request);
                return true;
            } catch (SipException e) {
                logger.error("sendRequest error!", e);
            }
        }
        return false;
    }

    @Override
    public boolean unRegister(SipPlatform sipPlatform, SipDevice sipDevice, SipSubscribe.Event event) {
        String tm = Long.toString(System.currentTimeMillis());
        Request request = null;
        CallIdHeader callIdHeader = udpSipProvider.getNewCallId();
        try {
            request = headerProviderPlatformProvider.createUnRegisterRequest(sipPlatform, sipDevice, 1L, "FromRegister" + tm, null, callIdHeader);
        } catch (Exception e) {
            logger.error("createRegisterRequest error!", e);
        }
        if (request != null) {
            sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), event);
            try {
                logger.info("要发送的注销消息:\n{}", request);
                udpSipProvider.sendRequest(request);
                return true;
            } catch (SipException e) {
                logger.error("sendRequest error!", e);
            }
        }
        return false;
    }

    @Override
    public boolean unRegister(SipPlatform sipPlatform, SipDevice sipDevice, String callId, WWWAuthenticateHeader www, SipSubscribe.Event event) {
        String tm = Long.toString(System.currentTimeMillis());
        Request request = null;
        CallIdHeader callIdHeader = udpSipProvider.getNewCallId();
        try {
            callIdHeader.setCallId(callId);
            request = headerProviderPlatformProvider.createUnRegisterRequest(sipPlatform, sipDevice, "FromRegister" + tm, null, www, callIdHeader);
        } catch (Exception e) {
            logger.error("createRegisterRequest error!", e);
        }
        if (request != null) {
            sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), event);
            try {
                logger.info("要发送的注销消息:\n{}", request);
                udpSipProvider.sendRequest(request);
                return true;
            } catch (SipException e) {
                logger.error("sendRequest error!", e);
            }
        }
        return false;
    }

    @Override
    public String keepalive(SipPlatform sipPlatform, SipDevice sipDevice, SipSubscribe.Event okEvent) {
        String callId = null;
        try {
            StringBuffer keepaliveXml = new StringBuffer(200);
            keepaliveXml.append("<?xml version=\"1.0\"?>\r\n");
            keepaliveXml.append("<Notify>\r\n");
            keepaliveXml.append("<CmdType>Keepalive</CmdType>\r\n");
            keepaliveXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
            keepaliveXml.append("<DeviceID>" + sipDevice.getDeviceId() + "</DeviceID>\r\n");
            keepaliveXml.append("<Status>OK</Status>\r\n");
            keepaliveXml.append("</Notify>\r\n");
            CallIdHeader callIdHeader = udpSipProvider.getNewCallId();
            Request request = headerProviderPlatformProvider.createKeetpaliveMessageRequest(
                    sipPlatform,
                    sipDevice,
                    keepaliveXml.toString(),
                    "z9hG4bK-" + UUID.randomUUID().toString().replace("-", ""),
                    UUID.randomUUID().toString().replace("-", ""),
                    null,
                    callIdHeader);
            logger.info("发送心跳消息");
            sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), okEvent);
            udpSipProvider.sendRequest(request);
            callId = callIdHeader.getCallId();
        } catch (ParseException | InvalidArgumentException | SipException e) {
            logger.error("心跳消息发送异常!", e);
        }
        return callId;
    }

    /**
     * 向上级回复目录信息
     *
     * @param sipDevice 设备信息
     * @return
     */
    @Override
    public boolean catalogResponse(SipPlatform sipPlatform, SipDevice sipDevice, String sn, String fromTag) {
        try {
            OrgnizationInfo deviceInfo = httpUtil.getDeviceInfo();
            if (deviceInfo == null){
                return false;
            }
            StringBuffer catalogXml = new StringBuffer();
            String CatalogTop=xml.setCatalogTop(sn,sipDevice.getDeviceId(),
                    deviceInfo.getTotalNum()+"",
                    deviceInfo.getOnlineNum()+"");
            catalogXml.append(CatalogTop);
            for (JTToGB jtToGB : deviceInfo.getJtToGBList()){
                String devicelistXml;
                if (jtToGB.getNodeType().equals("camera")){
                     devicelistXml = xml.setDeviceList(jtToGB.getParentDeviceId(),
                            jtToGB.getDeviceId(),
                            jtToGB.getVechecileNo(),
                            sipDevice.getManufacturer(),
                            jtToGB.getStatus(),0);
                    caffeineCache.put(jtToGB.getDeviceId(),jtToGB.getVehicleId());
                }else{
                   devicelistXml = xml.setDeviceList(jtToGB.getParentDeviceId(),
                            jtToGB.getDeviceId(),
                            jtToGB.getVechecileNo(),
                            sipDevice.getManufacturer(),
                            jtToGB.getStatus(),1);

                }
                catalogXml.append(devicelistXml);
            }
            catalogXml.append("</DeviceList>\n" +
                    "</Response>");
            //}
            // callid
            CallIdHeader callIdHeader = udpSipProvider.getNewCallId();
            Request request = headerProviderPlatformProvider.createMessageRequest(sipPlatform, sipDevice, catalogXml.toString(), fromTag, callIdHeader);
            logger.info("要发送的catalog消息:\n{}", request);
            udpSipProvider.sendRequest(request);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 向上级回复设备信息
     *
     * @param sipDevice 设备信息
     * @return
     */
    @Override
    public boolean deviceInfoResponse(SipPlatform sipPlatform, SipDevice sipDevice, String sn, String fromTag) {
        try {
            String deviceInfoXml = xml.setDeviceInfo(sn, sipDevice.getDeviceId(), sipDevice.getName(), sipDevice.getManufacturer());
            CallIdHeader callIdHeader = udpSipProvider.getNewCallId();
            Request request = headerProviderPlatformProvider.createMessageRequest(sipPlatform, sipDevice, deviceInfoXml.toString(), fromTag, callIdHeader);
            logger.info("要发送的deviceInfo消息:\n{}", request);
            udpSipProvider.sendRequest(request);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public boolean recordInfoResponse(SipPlatform sipPlatform, SipDevice sipDevice, String fromTag, Element queryRecordInfoElement) {
        Element snElement = queryRecordInfoElement.element("SN");
        String sn = snElement.getText();
        String startTime = queryRecordInfoElement.element("StartTime").getText();
        String deviceID = queryRecordInfoElement.element("DeviceID").getText();
        String endTime = queryRecordInfoElement.element("EndTime").getText();
        LocalDateTime startLocalDateTime = DateUtil.toLocalDateTime(startTime);
        LocalDateTime endLocalDateTime = DateUtil.toLocalDateTime(endTime);
        boolean hasRecordInfo = true;
        LocalDate today = LocalDate.now(ZoneId.systemDefault());
        if (startLocalDateTime.toLocalDate().isAfter(today)
                || endLocalDateTime.toLocalDate().isBefore(today)
                || endLocalDateTime.isBefore(startLocalDateTime)) {
            hasRecordInfo = false;
        }
        try {
            Object ifPresent = caffeineCache.getIfPresent(deviceID);
            if (ifPresent==null){
               logger.error("设备ID：{}在缓存中不存在",deviceID);
               return false;
            }
            String[] s = ifPresent.toString().split("_");
            BackTime backTime = httpUtil.getBackTime(s[0], Integer.parseInt(s[1]), 0, 0, 0, startTime, endTime);
            String recordInfoTop = xml.setRecordInfoTop(sn,backTime.getDeviceId(), backTime.getName(), backTime.getTotalNum());
            StringBuffer catalogXml = new StringBuffer();
            catalogXml.append(recordInfoTop);
            for (BackTimeList backTimeList : backTime.getBackTimeList()){
                String start =formatDateTime(backTimeList.getStartTime());
                String end =formatDateTime(backTimeList.getEndTime());
                String recordList = xml.setRecordList(backTimeList.getDeviceId(), backTimeList.getName(),
                        start+"_"+end,start, end);
                catalogXml.append(recordList);
            }
            catalogXml.append("    </RecordList>\n" +
                    "</Response>");
            CallIdHeader callIdHeader = udpSipProvider.getNewCallId();
            Request request = headerProviderPlatformProvider.createMessageRequest(sipPlatform, sipDevice, catalogXml.toString(), fromTag, callIdHeader);
            logger.info("要发送的recordInfo消息:\n{}", request);
            udpSipProvider.sendRequest(request);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

}
